package cc.eddic.practice.concurrency.impl;

import cc.eddic.practice.concurrency.ExecutorServiceUtil;
import cc.eddic.practice.concurrency.LogItem;
import cc.eddic.practice.concurrency.LogParser;
import lombok.extern.slf4j.Slf4j;
import lombok.val;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
public class LogParserExecutorImpl implements LogParser {
    @Override
    public Map<String, List<LogItem>> parse(String folderName) {

        File dir = new File(folderName);

        List<File> allFileList = new ArrayList<>();
        if (!dir.exists()) {
            System.out.println("目录不存在");
            return null;
        }

        getAllFile(dir, allFileList);
        log.debug("该文件夹下共有" + allFileList.size() + "个文件");

        List<String> logFilePathList = new ArrayList<>();

        for (File file : allFileList) {
            if (file.getName().contains("log")) {
                logFilePathList.add(file.getPath());
            }
        }
        log.debug(".log文件个数：" + logFilePathList.size());

        CountDownLatch latch = new CountDownLatch(logFilePathList.size());

        Map<String, List<LogItem>> mapForFilepathAndLine = new HashMap<>();

        ExecutorService executorService = Executors.newFixedThreadPool(8);


        for (String p : logFilePathList) {

            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    line(p, mapForFilepathAndLine, latch);
                }
            });

        }

        try {
            //阻塞，任务都被提交完后主线程一直等
            latch.await();
        } catch (InterruptedException e) {
            log.error(e.getMessage());
        }

        ExecutorServiceUtil.shutdown(executorService);
        return mapForFilepathAndLine;
    }

//    LogParserExecutorImpl logParserExecutor = new LogParserExecutorImpl();
    // CountDownLatch latch = new CountDownLatch(logFilePathList.size());

    private void line(String p, Map<String, List<LogItem>> mapForFilepathAndLine, CountDownLatch latch) {
        if (log.isDebugEnabled()) {
            log.debug("{}", p);
        }
        List<LogItem> logItemsList = new ArrayList<>();
        LogItemParserImpl logItemParser = new LogItemParserImpl();

        List<String> linesList = readList(p);
        for (String line : linesList) {
            Optional<LogItem> logItem = logItemParser.parse(line);

            logItem.ifPresent(logItemsList::add);
        }
        mapForFilepathAndLine.put(p, logItemsList);
        latch.countDown();
    }


    public static void getAllFile(File fileInput, List<File> allFileList) {
        // 获取文件列表
        File[] fileList = fileInput.listFiles();
        assert fileList != null;
        for (File file : fileList) {
            if (file.isDirectory()) {
                // 递归处理文件夹
                // 如果不想统计子文件夹则可以将下一行注释掉
                getAllFile(file, allFileList);
            } else {
                // 如果是文件则将其加入到文件数组中
                allFileList.add(file);
            }
        }
    }


    //读取文件里的每一行
    public Stream<String> read(String textFileName) throws IOException {
        val p = Paths.get(textFileName);
        return Files.lines(p);
    }

    public List<String> readList(String textFileName) {
        try {
            return read(textFileName).collect(Collectors.toList());
        } catch (IOException e) {
            return null;
        }

    }


}



